#include "TcpServer.hpp"
#include "Comm.hpp"
#include <memory>
#include <unordered_map>
#include <functional>
#include <string>
#include <algorithm>
#include "Translater.hpp"
#include "Log.hpp"
#include "InetAddr.hpp"
#include "Daemon.hpp"

Translater translater;  // 全局

// 使用手册
void Usage(std::string proc)
{
    std::cout << "Usage : \n\t" << proc << " local_port\n" << std::endl;
}

// 未来的服务是部署在云服务器上的，我们怎么知道我们的服务未来在任何一个时刻，都是健康的呢？
// 我们可以定期（30s）向服务器发送最小服务请求，如果得到了回复，说明我们的服务器是正常的。
// 这种机制我们称之为心跳机制
void Ping(int sockfd, InetAddr &addr)    // 不管用户输入什么都返回pong
{
    lg.LogMessage(Debug, "%s select %s success, fd: %d\n", addr.PrintDebug().c_str(), "ping", sockfd);
    char buffer[1024];
    ssize_t n = read(sockfd, buffer, sizeof(buffer) - 1);
    if(n > 0)
    {
        std::string out = "pong";
        write(sockfd, out.c_str(), out.size());
    }
    else if(n == 0)
    {
        lg.LogMessage(Info, "client quit...\n");
    }
    else
    {
        lg.LogMessage(Error, "read socket error, errno code: %d, error string: %s\n", errno, strerror(errno));
    }
}

void Translate(int sockfd, InetAddr &addr)
{
    lg.LogMessage(Debug, "%s select %s success, fd: %d\n", addr.PrintDebug().c_str(), "translate", sockfd);
    // translater.debug();     // for debug
    char wordbuf[128];
    ssize_t n = read(sockfd, wordbuf, sizeof(wordbuf) - 1);
    if(n > 0)
    {  
        wordbuf[n] = 0;
        std::string chinese = translater.Excute(wordbuf);
        write(sockfd, chinese.c_str(), chinese.size());
        lg.LogMessage(Debug, "%s translate service, %s->%s\n", addr.PrintDebug().c_str(), wordbuf, chinese.c_str());
    }
}

// 字符串小写转大写
void Transform(int sockfd, InetAddr &addr)
{
    lg.LogMessage(Debug, "%s select %s success, fd: %d\n", addr.PrintDebug().c_str(), "Transform", sockfd);
    char buffer[128];
    int n = read(sockfd, buffer, sizeof(buffer) - 1);
    if(n > 0)
    {
        buffer[n] = 0;
        std::string message = buffer;
        std::transform(message.begin(), message.end(), message.begin(), [](unsigned char c){
            return std::toupper(c);
        });
        write(sockfd, message.c_str(), message.size());
    }
}

int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        Usage(argv[0]);
        return Usage_Err;
    }
    uint16_t port = std::stoi(argv[1]);
    // 守护进程化
    Daemon(false, false);
    lg.Enable(ClassFile);

    std::unique_ptr<TcpServer> tsvr = std::unique_ptr<TcpServer>(new TcpServer(port));
    tsvr->Init();

    // 注册服务
    tsvr->Register("ping", Ping);
    tsvr->Register("translate", Translate);
    tsvr->Register("transform", Transform);

    tsvr->Start();

    return 0;
}